package org.monitoringtools.elements;

import static org.monitoringtools.util.AssertUtil.assertNotNull;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.monitoringtools.elements.impl.BasicCounter;
import org.monitoringtools.elements.impl.TimeBasedCounter;

public class Monitor {

    private Map<String, Counter> counters = new HashMap<String, Counter>();

    private final String id;

    public Monitor(String id) {
        assertNotNull(this.id = id);
        this.counters.put(id, new BasicCounter(id));

        addCounter(TimeUnit.MILLISECONDS, 1);
        addCounter(TimeUnit.SECONDS, 1);
        addCounter(TimeUnit.MINUTES, 1);
        addCounter(TimeUnit.HOURS, 1);
        addCounter(TimeUnit.DAYS, 1);
    }

    /**
     * Creates a new time counter with specific renew interval.
     * 
     * @param unit
     * @param amount
     * @param id
     */
    private void addCounter(TimeUnit timeUnit, Integer delta) {
        assertNotNull(timeUnit, delta);
        this.counters.put(timeUnit.name(), new TimeBasedCounter(timeUnit.name(), timeUnit, delta));
    }

    public synchronized long failure() {
        return this.counters.get(id).failure();
    }

    public Counter getCounter(String id) {
        return this.counters.get(id);
    }

    public String getId() {
        return id;
    }

    public void logFailure() {
        this.log(false);
    }

    public void logSuccess() {
        this.log(true);
    }

    public synchronized void reset() {
        final Iterator<String> it = this.counters.keySet().iterator();
        while (it.hasNext())
            this.counters.get(it.next()).reset();
    }

    public synchronized long success() {
        return this.counters.get(id).success();
    }

    public synchronized long total() {
        return this.counters.get(id).total();
    }

    private synchronized void log(boolean isSuccess) {
        final Iterator<String> it = this.counters.keySet().iterator();
        while (it.hasNext())
            this.counters.get(it.next()).log(isSuccess);
    }
}